package net.jmchilton.spring.collect.spec;

import java.io.File;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

import net.jmchilton.spring.collect.spec.namespace.Namespace;
import net.jmchilton.spring.collect.spec.namespace.StaticFactory;

/**
 * Some convenience methods to hide JAXB and simplify reading
 * and writing spec XML files.
 * 
 * @author John Chilton
 *
 */
class NamespaceXmlUtils {
  /**
   * @param xmlFile A file containing a spec.
   * @return The object representation of the spec fined by xmlFile.
   */
  static Namespace getNamespace(final File xmlFile) {
    try {
      final JAXBContext jaxbContext = JAXBContext.newInstance(Namespace.class);
      final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      final Namespace namespace = (Namespace) unmarshaller.unmarshal(xmlFile);
      return namespace;
    } catch(final JAXBException e) {
      throw new RuntimeException("Error deserializing XML, this likely because JAXB is not configured properly. Are using Java 6+?", e);
    }
  }
  
  static String toString(final StaticFactory element) {
    try {
      final JAXBContext jaxbContext = JAXBContext.newInstance(StaticFactory.class);
      final Marshaller marshaller = jaxbContext.createMarshaller();
      final JAXBElement<StaticFactory> jaxbWrapper = new JAXBElement<StaticFactory>(new QName("http://jmchilton.net/spring/collect/spec", "staticFactory"), StaticFactory.class, element);
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      final StringWriter writer = new StringWriter();
      marshaller.marshal(jaxbWrapper, writer);    
      final String fullXml = writer.toString();
      return fullXml.substring(fullXml.indexOf("?>") + 3);
    } catch(final JAXBException e) {
      throw new RuntimeException(e);
    }    
  }
  
  /**
   * 
   * @param xmlFile File to serialize namespace object to.
   * @param namespace Namespace object to serialize to file.
   */
  static void writeNamespace(final File xmlFile, final Namespace namespace) {
    try {
      final JAXBContext jaxbContext = JAXBContext.newInstance(Namespace.class);
      final Marshaller marshaller = jaxbContext.createMarshaller();      
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.marshal(namespace, xmlFile);
    } catch(final JAXBException e) {
      throw new RuntimeException("Error serializing XML, this likely because JAXB is not configured properly. Are using Java 6+?", e);
    }
  }
  
  
  
}
